/**
 * @file list.c
 * @author lcz (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2022-10-22
 * 
 * @copyright Copyright (c) 2022
 * 
 */

#include "tools/list.h"
/**
 * 初始化链表
 * @param list 待初始化的链表
 */
void list_init(list_t *list){
    list->first =list->last = (list_t *)0;
    list->count = 0;
}

/**
 * 将指定表项插入到指定链表的头部
 * @param list 待插入的链表
 * @param node 待插入的结点
 */
void list_insert_first(list_t *list, list_node_t *node)
{
    node->next = list->first;
    node->pre = (list_node_t *)0;
    if (list_is_empty(list))
    {
        list->last = list->first = node;
    }
    else
    {
        list->first->pre = node;
        list->first = node;
    }
    list->count++;
}
/**
 * 将指定表项插入到指定链表的尾部
 * @param list 操作的链表
 * @param node 待插入的结点
 */
void list_insert_last(list_t *list, list_node_t *node)
{
    node->pre = list->last;
    node->next = (list_node_t *)0;
    if (list_is_empty(list))
    {
        list->last = list->first = node;
    }
    else
    {
        list->last->next = node;
        list->last = node;
    }
    list->count++;
}

// remove
/**
 * @brief remove first
 * 
 * @param list 
 * @return list_node_t* 
 */
list_node_t *list_remove_first(list_t *list)
{
    if (list_is_empty(list))
    {
        return (list_node_t *)0;
    }
    list_node_t *remove_node = list->first;
    list->first = remove_node->next;
    if (list->first == (list_node_t *)0)
    {
        list->last = (list_node_t *)0;
    }
    else
    {
        list->first->pre = (list_node_t *)0;
    }

    remove_node->pre = remove_node->next = (list_node_t *)0 ;
    list->count--;
    return remove_node;
}

/**
 * @brief remove any location node
 * 
 * @param list 
 * @param node 
 * @return list_node_t* 
 */
list_node_t *list_remove(list_t *list, list_node_t *node)
{

    if (node == list->first)
    {
        list->first = node->next;
    }
    if (node == list->last)
    {
        list->last = node->pre;
    }

    if (node->pre)
    {
        node->pre->next = node->next;
    }

    if (node->next)
    {
        node->next->pre = node->pre;
    }

    node->pre = node->next = (list_node_t *)0;
    list->count--;
    return node;
}

void list_test(void){
    list_t list;
    list_init(&list);
    log_printf("first%x : last%x : count %d", list_first(&list), list_last(&list), list_count(&list));

    list_node_t nodes[5];
    for (int i = 0; i < 5; i++)
    {
        list_node_t * node=&nodes[i];
        log_printf("node%x : count %d", node,i);
        list_insert_first(&list, node);
    }

    list_init(&list);

    for (int i = 0; i < 5; i++)
    {
        list_node_t *node = &nodes[i];
        log_printf("node%x : count %d", node, i);
        list_insert_last(&list, node);
    }

    for (int i = 0; i < 5; i++)
    {
        list_node_t *node = list_remove_first(&list);
        log_printf("node%x : count %d", node, i);
    }

    for (int i = 0; i < 5; i++)
    {
        list_node_t *node = &nodes[i];
        log_printf("node%x : count %d", node, i);
        list_insert_first(&list, node);
    }

    // remove
    list_node_t *node = &nodes[2];
    list_node_t *temp = list_remove(&list, node);
    log_printf("node%x ", temp);

     node = &nodes[0];
     temp = list_remove(&list, node);
    log_printf("node%x ", temp);

     node = &nodes[4];
     temp = list_remove(&list, node);
    log_printf("node%x ", temp);

    // test macro
    struct type_t{
        int i;
        int b;
        list_node_t node;
    }v={0x123456,0x123456};

    list_node_t * v_node=&v.node;
    struct type_t  *p = list_node_parent(v_node, struct type_t, node);
    if (p->i != 0x123456)
    {
        log_printf("macro error");
    }else{
        log_printf("macro successful!!");
    }
    
    // ()
}
